using System;
using System.Collections.Generic;
using NHibernate.Validator.Cfg;
using NHibernate.Validator.Engine;
using Environment = NHibernate.Validator.Cfg.Environment;

namespace HashFoo.Nhib.Core
{
    /// <summary>
    /// Nhibernate 3.2 does not play nice with validation -- excluding.  DMF 20111017
    /// A default validation configuration for integration into the NHibernate system.  ApplyToDDL and AutregisterListeners are both enabled.
    /// </summary>
    public class NhValidationConfiguration : INHVConfiguration
    {
        private readonly IEnumerable<Type> _entityTypeInspectors = new List<Type>();

        private readonly IList<MappingConfiguration> _mappings = new List<MappingConfiguration>();

        private readonly IDictionary<string, string> _properties =
            new Dictionary<string, string>
            {
                { Environment.ApplyToDDL, "true" },
                { Environment.AutoregisterListeners, "true" }
            };

        #region INHVConfiguration Members
        /// <summary>
        /// Assembly qualified name for shared engine provider.  Not implemented
        /// </summary>
        string INHVConfiguration.SharedEngineProviderClass
        {
            get { throw new InvalidOperationException("This is only valid in an app config"); }
        }

        /// <summary>
        /// Configured properties.
        /// </summary>
        public IDictionary<string, string> Properties
        {
            get { return _properties; }
        }

        /// <summary>
        /// Configured Mappings.
        /// </summary>
        IList<MappingConfiguration> INHVConfiguration.Mappings
        {
            get { return _mappings; }
        }

        /// <summary>
        /// Configured Entity Type Inspectors.
        /// </summary>
        /// <seealso cref="T:NHibernate.Validator.Engine.IEntityTypeInspector"/>
        IEnumerable<Type> INHVConfiguration.EntityTypeInspectors
        {
            get { return _entityTypeInspectors; }
        }
        #endregion

        /// <summary>
        /// Initializes nhibernate to use the validation.  This effects schema generation, and insert/updates.
        /// </summary>
        /// <param name="config">The NHibernate configuration to initialize for validation</param>
        public static void InitializeNhibernate(NHibernate.Cfg.Configuration config)
        {
            var engine = new ValidatorEngine();
            var validationConfig = new NhValidationConfiguration();
            engine.Configure(validationConfig);

            // ReSharper disable InvokeAsExtensionMethod
            // its clearer explicitly call on the static class
            ValidatorInitializer.Initialize(config, engine);
            // ReSharper restore InvokeAsExtensionMethod
        }

    }
}